package com.regent.central.bill.web;

import com.regent.central.infrastructure.web.BasicResponse;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;

import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Map;

/**
 * 时间戳多了".0"结尾的删除
 *
 * @author 杨昌沛 646742615@qq.com
 * @date 2018-07-05 9:49
 **/
@Aspect
public class TimestampInterceptor {

    @Pointcut("execution(* com.regent.central.bill.web..*Controller.*(..))")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        Object result = point.proceed();
        if (result instanceof BasicResponse) handle(result);
        return result;
    }

    private void handle(Object value) throws Exception {
        if (value == null) return;
        if (value instanceof Number || value instanceof Date) return;
        Class<?> clazz = value.getClass();
        if (clazz.isPrimitive() || clazz.isEnum()) return;
        if (clazz.isArray()) {
            int length = Array.getLength(value);
            for (int i = 0; i < length; i++) handle(Array.get(value, i));
        } else if (value instanceof Iterable<?>) {
            Iterable<?> iterable = (Iterable<?>) value;
            for (Object val : iterable) handle(val);
        } else if (value instanceof Map<?, ?>) {
            Map<?, ?> map = (Map<?, ?>) value;
            for (Object val : map.values()) handle(val);
        } else {
            PropertyDescriptor[] descriptors = Introspector.getBeanInfo(clazz).getPropertyDescriptors();
            for (PropertyDescriptor descriptor : descriptors) {
                String name = descriptor.getName();
                if ("class".equals(name)) continue;
                Method getter = descriptor.getReadMethod();
                Method setter = descriptor.getWriteMethod();
                if (getter == null || setter == null) continue;
                Object val = getter.invoke(value);
                if (val instanceof String) {
                    String str = (String) val;
                    if (str.matches("\\d{4}-\\d{1,2}-\\d{1,2} \\d{1,2}:\\d{1,2}:\\d{1,2}\\.\\d+")) {
                        str = str.substring(0, str.length() - 2);
                        setter.invoke(value, str);
                    }
                } else {
                    handle(val);
                }
            }
        }
    }

}
